home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 22 / Cream of the Crop 22.iso / comm / rzsz0916.zip / RBSB.C < prev    next >
C/C++ Source or Header  |  1994-05-21  |  11KB  |  550 lines

  1. /*
  2.  *    V7/BSD HACKERS:  SEE NOTES UNDER mode(2) !!!
  3.  *
  4.  *   This file is #included so the main file can set parameters such as HOWMANY.
  5.  *   See the main files (rz.c/sz.c) for compile instructions.
  6.  */
  7.  
  8. char *Copyr = "Copyright 1994 Omen Technology Inc All Rights Reserved";
  9.  
  10. #ifdef V7
  11. #include <sys/types.h>
  12. #include <sys/stat.h>
  13. #define STAT
  14. #include <sgtty.h>
  15. #define OS "V7/BSD"
  16. char *getenv(), *ttyname();
  17. #ifdef LLITOUT
  18. long Locmode;        /* Saved "local mode" for 4.x BSD "new driver" */
  19. long Locbit = LLITOUT;    /* Bit SUPPOSED to disable output translations */
  20. #include <strings.h>
  21. #endif
  22. #endif
  23.  
  24. #ifdef USG
  25. #include <sys/types.h>
  26. #include <sys/stat.h>
  27. #define STAT
  28. #include <termio.h>
  29. #define OS "SYS III/V"
  30. #define MODE2OK
  31. #include <string.h>
  32. #ifndef OLD
  33. #include <stdlib.h>
  34. #endif
  35. #include <unistd.h>
  36. #endif
  37.  
  38. #ifdef POSIX
  39. #define USG
  40. #include <sys/types.h>
  41. #include <sys/stat.h>
  42. #include <sys/ioctl.h>
  43. #define STAT
  44. #include <termios.h>
  45. #define OS "POSIX"
  46. #include <string.h>
  47. #include <stdlib.h>
  48. #include <unistd.h>
  49. #ifndef READCHECK
  50. #ifndef FIONREAD
  51. #define SV
  52. #endif
  53. #endif
  54. #endif
  55.  
  56. #ifdef OLD
  57. char *ttyname();
  58. char *getenv();
  59. #define time_t long
  60. #endif
  61.  
  62.  
  63. #ifdef T6K
  64. #include <sys/ioctl.h>        /* JPRadley: for the Tandy 6000 */
  65. #endif
  66.  
  67. #include <setjmp.h>
  68.  
  69. #if HOWMANY  > 255
  70. Howmany must be 255 or less
  71. #endif
  72.  
  73.  /*
  74.  *  Some systems (Venix, Coherent, Regulus) may not support tty raw mode
  75.  *  read(2) the same way as Unix. ONEREAD must be defined to force one
  76.  *  character reads for these systems. Added 7-01-84 CAF
  77.  */
  78.  
  79. #define sendline(c) putc(c & 0377, Ttystream)
  80. #define xsendline(c) putc(c, Ttystream)
  81.  
  82. char *Nametty;
  83. FILE *Ttystream;
  84. int Tty;
  85. char linbuf[HOWMANY];
  86. char xXbuf[BUFSIZ];
  87. int Lleft=0;        /* number of characters in linbuf */
  88. jmp_buf tohere;        /* For the interrupt on RX timeout */
  89. #ifdef ONEREAD
  90. /* Sorry, Regulus and some others don't work right in raw mode! */
  91. int Readnum = 1;    /* Number of bytes to ask for in read() from modem */
  92. #else
  93. int Readnum = HOWMANY;    /* Number of bytes to ask for in read() from modem */
  94. #endif
  95. int Verbose=0;
  96.  
  97.  
  98. /*
  99.  *  The following uses an external rdchk() routine if available,
  100.  *  otherwise defines the function for BSD or fakes it for SYSV.
  101.  */
  102.  
  103. #ifndef READCHECK
  104. #ifdef FIONREAD
  105. #define READCHECK
  106. /*
  107.  *  Return non 0 iff something to read from io descriptor f
  108.  */
  109. rdchk(f)
  110. {
  111.     static long lf;
  112.  
  113.     ioctl(f, FIONREAD, &lf);
  114.     return ((int) lf);
  115. }
  116.  
  117. #else        /* FIONREAD */
  118.  
  119. #ifdef SV
  120. #define READCHECK
  121. #include <fcntl.h>
  122.  
  123. int checked = 0;
  124. /*
  125.  * Nonblocking I/O is a bit different in System V, Release 2
  126.  *  Note: this rdchk vsn throws away a byte, OK for ZMODEM
  127.  *  sender because protocol design anticipates this problem.
  128.  */
  129. #define EATSIT
  130. rdchk(f)
  131. {
  132.     int lf, savestat;
  133.     static char bchecked;
  134.  
  135.     savestat = fcntl(f, F_GETFL) ;
  136. #ifdef O_NDELAY
  137.     fcntl(f, F_SETFL, savestat | O_NDELAY) ;
  138. #else
  139.     fcntl(f, F_SETFL, savestat | O_NONBLOCK) ;
  140. #endif
  141.     lf = read(f, &bchecked, 1) ;
  142.     fcntl(f, F_SETFL, savestat) ;
  143.     checked = bchecked & 0377;    /* force unsigned byte */
  144.     return(lf) ;
  145. }
  146. #endif
  147. #endif
  148. #endif
  149.  
  150.  
  151. struct {
  152.     unsigned baudr;
  153.     int speedcode;
  154. } speeds[] = {
  155.     110,    B110,
  156. #ifdef B150
  157.     150,    B150,
  158. #endif
  159.     300,    B300,
  160.     600,    B600,
  161.     1200,    B1200,
  162.     2400,    B2400,
  163.     4800,    B4800,
  164.     9600,    B9600,
  165. #ifdef B19200
  166.     19200,    B19200,
  167. #endif
  168. #ifdef EXTA
  169.     19200,    EXTA,
  170. #endif
  171. #ifdef B38400
  172.     38400,    B38400,
  173. #endif
  174. #ifdef EXTB
  175.     38400,    EXTB,
  176. #endif
  177.     0,    0
  178. };
  179. static unsigned
  180. getspeed(code)
  181. {
  182.     register n;
  183.  
  184.     for (n=0; speeds[n].baudr; ++n)
  185.         if (speeds[n].speedcode == code)
  186.             return speeds[n].baudr;
  187.     if (code > 49)
  188.         return ((unsigned)code);
  189.     return 1;    /* Assume fifo if ioctl failed */
  190. }
  191.  
  192.  
  193. #ifdef ICANON
  194. #ifdef POSIX
  195. struct termios oldtty, tty;
  196. #else
  197. struct termio oldtty, tty;
  198. #endif
  199. #else
  200. struct sgttyb oldtty, tty;
  201. struct tchars oldtch, tch;
  202. #endif
  203.  
  204. /*
  205.  * mode(n)
  206.  *  3: save old tty stat, set raw mode with flow control
  207.  *  2: set XON/XOFF for sb/sz with ZMODEM or YMODEM-g
  208.  *  1: save old tty stat, set raw mode 
  209.  *  0: restore original tty mode
  210.  */
  211. mode(n)
  212. {
  213.     static did0 = FALSE;
  214.  
  215.     vfile("mode:%d", n);
  216.     switch(n) {
  217. #ifdef USG
  218.     case 2:        /* Un-raw mode used by sz, sb when -g detected */
  219. #ifdef POSIX
  220.         if(!did0)
  221.             (void) tcgetattr(Tty, &oldtty);
  222. #else
  223.         if(!did0)
  224.             (void) ioctl(Tty, TCGETA, &oldtty);
  225. #endif
  226.         tty = oldtty;
  227.  
  228.         tty.c_iflag = BRKINT|IXON;
  229.  
  230.         tty.c_oflag = 0;    /* Transparent output */
  231.  
  232.         tty.c_cflag &= ~(PARENB|CSIZE);        /* Disable parity */
  233.         tty.c_cflag |= (CREAD|CS8);    /* Set character size = 8 */
  234.  
  235.  
  236. #ifdef READCHECK
  237.         tty.c_lflag = Zmodem ? 0 : ISIG;
  238.         tty.c_cc[VINTR] = Zmodem ? -1:030;    /* Interrupt char */
  239. #else
  240.         tty.c_lflag = ISIG;
  241.         tty.c_cc[VINTR] = Zmodem ? 03:030;    /* Interrupt char */
  242. #endif
  243.         tty.c_cc[VQUIT] = -1;            /* Quit char */
  244. #ifdef NFGVMIN
  245.         tty.c_cc[VMIN] = 1;
  246. #else
  247.         tty.c_cc[VMIN] = 3;     /* This many chars satisfies reads */
  248. #endif
  249.         tty.c_cc[VTIME] = 1;    /* or in this many tenths of seconds */
  250.  
  251. #ifdef POSIX
  252.         (void) tcsetattr(Tty, TCSADRAIN, &tty);
  253. #else
  254.         (void) ioctl(Tty, TCSETAW, &tty);
  255. #endif
  256.         did0 = TRUE;
  257.         return OK;
  258.     case 1:
  259.     case 3:
  260. #ifdef POSIX
  261.         if(!did0)
  262.             (void) tcgetattr(Tty, &oldtty);
  263. #else
  264.         if(!did0)
  265.             (void) ioctl(Tty, TCGETA, &oldtty);
  266. #endif
  267.         tty = oldtty;
  268.  
  269.         tty.c_iflag = n==3 ? (IXON|IXOFF) : IXOFF;
  270.  
  271.         tty.c_lflag = 0;
  272.  
  273.         tty.c_oflag = 0;
  274.  
  275.         tty.c_cflag &= ~(CSIZE|PARENB);    /* disable parity */
  276.         tty.c_cflag |= CS8;    /* Set character size = 8 */
  277. #ifdef NFGVMIN
  278.         tty.c_cc[VMIN] = 1; /* This many chars satisfies reads */
  279. #else
  280.         tty.c_cc[VMIN] = HOWMANY; /* This many chars satisfies reads */
  281. #endif
  282.         tty.c_cc[VTIME] = 1;    /* or in this many tenths of seconds */
  283. #ifdef POSIX
  284.         (void) tcsetattr(Tty, TCSADRAIN, &tty);
  285. #else
  286.         (void) ioctl(Tty, TCSETAW, &tty);
  287. #endif
  288.         did0 = TRUE;
  289. #ifdef POSIX
  290.         Baudrate = getspeed(cfgetospeed(&tty));
  291. #else
  292.         Baudrate = getspeed(tty.c_cflag & CBAUD);
  293. #endif
  294.         vfile("Baudrate = %u\n", Baudrate);
  295.         return OK;
  296. #endif
  297. #ifdef V7
  298.     /*
  299.      *  NOTE: this should transmit all 8 bits and at the same time
  300.      *   respond to XOFF/XON flow control.  If no FIONREAD or other
  301.      *   rdchk() alternative, also must respond to INTRRUPT char
  302.      *   This doesn't work with V7.  It should work with LLITOUT,
  303.      *   but LLITOUT was broken on the machine I tried it on.
  304.      */
  305.     case 2:        /* Un-raw mode used by sz, sb when -g detected */
  306.         if(!did0) {
  307.             ioctl(Tty, TIOCEXCL, 0);
  308.             ioctl(Tty, TIOCGETP, &oldtty);
  309.             ioctl(Tty, TIOCGETC, &oldtch);
  310. #ifdef LLITOUT
  311.             ioctl(Tty, TIOCLGET, &Locmode);
  312. #endif
  313.         }
  314.         tty = oldtty;
  315.         tch = oldtch;
  316. #ifdef READCHECK
  317.         tch.t_intrc = Zmodem ? -1:030;    /* Interrupt char */
  318. #else
  319.         tch.t_intrc = Zmodem ? 03:030;    /* Interrupt char */
  320. #endif
  321.         tty.sg_flags |= (ODDP|EVENP|CBREAK);
  322.         tty.sg_flags &= ~(ALLDELAY|CRMOD|ECHO|LCASE);
  323.         ioctl(Tty, TIOCSETP, &tty);
  324.         ioctl(Tty, TIOCSETC, &tch);
  325. #ifdef LLITOUT
  326.         ioctl(Tty, TIOCLBIS, &Locbit);
  327. #else
  328.         bibi(99);    /* un-raw doesn't work w/o lit out */
  329. #endif
  330.         did0 = TRUE;
  331.         return OK;
  332.     case 1:
  333.     case 3:
  334.         if(!did0) {
  335.             ioctl(Tty, TIOCEXCL, 0);
  336.             ioctl(Tty, TIOCGETP, &oldtty);
  337.             ioctl(Tty, TIOCGETC, &oldtch);
  338. #ifdef LLITOUT
  339.             ioctl(Tty, TIOCLGET, &Locmode);
  340. #endif
  341.         }
  342.         tty = oldtty;
  343.         tty.sg_flags |= (RAW|TANDEM);
  344.         tty.sg_flags &= ~ECHO;
  345.         ioctl(Tty, TIOCSETP, &tty);
  346.         did0 = TRUE;
  347.         Baudrate = getspeed(tty.sg_ospeed);
  348.         return OK;
  349. #endif
  350.     case 0:
  351.         if(!did0)
  352.             return ERROR;
  353. #ifdef USG
  354. #ifdef POSIX
  355.         (void) tcdrain(Tty);    /* Wait for output to drain */
  356.         (void) tcflush(Tty, TCIFLUSH);    /* Flush input queue */
  357.         (void) tcsetattr(Tty, TCSADRAIN, &oldtty);    /* Restore */
  358.         (void) tcflow(Tty, TCOON);    /* Restart output */
  359. #else
  360.         (void) ioctl(Tty, TCSBRK, 1);    /* Wait for output to drain */
  361.         (void) ioctl(Tty, TCFLSH, 1);    /* Flush input queue */
  362.         (void) ioctl(Tty, TCSETAW, &oldtty);    /* Restore modes */
  363.         (void) ioctl(Tty, TCXONC,1);    /* Restart output */
  364. #endif
  365. #endif
  366. #ifdef V7
  367.         ioctl(Tty, TIOCSETP, &oldtty);
  368.         ioctl(Tty, TIOCSETC, &oldtch);
  369.         ioctl(Tty, TIOCNXCL, 0);
  370. #ifdef LLITOUT
  371.         ioctl(Tty, TIOCLSET, &Locmode);
  372. #endif
  373. #endif
  374.  
  375.         return OK;
  376.     default:
  377.         return ERROR;
  378.     }
  379. }
  380.  
  381. sendbrk()
  382. {
  383. #ifdef V7
  384. #ifdef TIOCSBRK
  385. #define CANBREAK
  386.     sleep(1);
  387.     ioctl(Tty, TIOCSBRK, 0);
  388.     sleep(1);
  389.     ioctl(Tty, TIOCCBRK, 0);
  390. #endif
  391. #endif
  392. #ifdef USG
  393. #define CANBREAK
  394. #ifdef POSIX
  395.     tcsendbreak(Tty, 200);
  396. #else
  397.     ioctl(Tty, TCSBRK, 0);
  398. #endif
  399. #endif
  400. }
  401.  
  402. /* Initialize tty device for serial file xfer */
  403. inittty()
  404. {
  405.     if ((Nametty = ttyname(2)) && *Nametty) {
  406.         Tty = open(Nametty, 2);
  407.     } else {
  408.         Tty = open(Nametty = "/dev/tty", 2);
  409.     }
  410.  
  411.     if (Tty <= 0) {
  412.         perror(Nametty);  exit(2);
  413.     }
  414.     Ttystream = fdopen(Tty, "w");
  415. }
  416.  
  417. flushmoc()
  418. {
  419.     fflush(Ttystream);
  420. }
  421. flushmo()
  422. {
  423.     fflush(Ttystream);
  424. }
  425.  
  426. /*
  427.  * This version of readline is reasoably well suited for
  428.  * reading many characters.
  429.  *
  430.  * timeout is in tenths of seconds
  431.  */
  432. void
  433. alrm(c)
  434. {
  435.     longjmp(tohere, -1);
  436. }
  437. readline(timeout)
  438. int timeout;
  439. {
  440.     register n;
  441.     static char *cdq;    /* pointer for removing chars from linbuf */
  442.  
  443.     if (--Lleft >= 0) {
  444.         if (Verbose > 8) {
  445.             fprintf(stderr, "%02x ", *cdq&0377);
  446.         }
  447.         return (*cdq++ & 0377);
  448.     }
  449.     n = timeout/10;
  450.     if (n < 2)
  451.         n = 2;
  452.     if (Verbose > 5)
  453.         fprintf(stderr, "Calling read: alarm=%d  Readnum=%d ",
  454.           n, Readnum);
  455.     if (setjmp(tohere)) {
  456. #ifdef TIOCFLUSH
  457. /*        ioctl(Tty, TIOCFLUSH, 0); */
  458. #endif
  459.         Lleft = 0;
  460.         if (Verbose>1)
  461.             fprintf(stderr, "Readline:TIMEOUT\n");
  462.         return TIMEOUT;
  463.     }
  464.     signal(SIGALRM, alrm); alarm(n);
  465.     errno = 0;
  466.     Lleft=read(Tty, cdq=linbuf, Readnum);
  467.     alarm(0);
  468.     if (Verbose > 5) {
  469.         fprintf(stderr, "Read returned %d bytes errno=%d\n",
  470.           Lleft, errno);
  471.     }
  472.     if (Lleft < 1)
  473.         return TIMEOUT;
  474.     if (Verbose > 8) {
  475.         for (n = Lleft; --n >= 0; ) {
  476.             fprintf(stderr, "%02x ", *cdq&0377);
  477.         }
  478.         fprintf(stderr, "\n");
  479.     }
  480.     --Lleft;
  481.     return (*cdq++ & 0377);
  482. }
  483.  
  484.  
  485.  
  486. /*
  487.  * Purge the modem input queue of all characters
  488.  */
  489. purgeline()
  490. {
  491.     Lleft = 0;
  492. #ifdef USG
  493. #ifdef POSIX
  494.     tcflush(Tty, 0);
  495. #else
  496.     ioctl(Tty, TCFLSH, 0);
  497. #endif
  498. #else
  499.     lseek(Tty, 0L, 2);
  500. #endif
  501. }
  502.  
  503.  
  504. /* send cancel string to get the other end to shut up */
  505. canit()
  506. {
  507.     static char canistr[] = {
  508.      24,24,24,24,24,24,24,24,24,24,8,8,8,8,8,8,8,8,8,8,0
  509.     };
  510.  
  511.     zmputs(canistr);
  512.     Lleft=0;    /* Do read next time ... */
  513. }
  514.  
  515. /*
  516.  * Send a string to the modem, processing for \336 (sleep 1 sec)
  517.  *   and \335 (break signal)
  518.  */
  519. zmputs(s)
  520. char *s;
  521. {
  522.     register c;
  523.  
  524.     while (*s) {
  525.         switch (c = *s++) {
  526.         case '\336':
  527.             sleep(1); continue;
  528.         case '\335':
  529.             sendbrk(); continue;
  530.         default:
  531.             sendline(c);
  532.         }
  533.     }
  534.     flushmo();
  535. }
  536.  
  537.  
  538. /* VARARGS1 */
  539. vfile(f, a, b, c, d)
  540. char *f;
  541. long a, b, c, d;
  542. {
  543.     if (Verbose > 2) {
  544.         fprintf(stderr, f, a, b, c, d);
  545.         fprintf(stderr, "\n");
  546.     }
  547. }
  548.  
  549. /* End of rbsb.c */
  550.